<template>
    <div :class="cn" :ph-progress="progress" :style="style">
        <label class="ph-progress-label" ref="label" :style="labelTransform" :ph-label="progress"></label>
        <div class="ph-indicator-wrap">
            <div class="ph-indicator" :style="transform" ref="indicator"></div>
        </div>
    </div>
</template>
<script lang="ts">
import { defineComponent,computed,onMounted,ref } from 'vue'

export default defineComponent({
    props:{
        type:{type:String,default:"primary"},
        value:{type:Number,default:0},
        max:{type:Number,required:true},
        animate:{type:Boolean,default:false},
        striped:{type:Boolean,default:false},
        height:{type:Number,default:8},
        format:{type:String,default:"v/m"/* % */}
    },
    setup(props){
        const indicator = ref<HTMLElement|null>(null)
        const ofw = ref(0);
        const m = computed(()=>{
            return props.max;
        })
        const v = computed(()=>{
            return Math.max(0,props.value<m.value?props.value:m.value)
        })
        const bh = computed(()=>{
            let h = Math.max(props.height,0)
                h = Math.min(h,32)
                return h;
        })
        const per = computed(()=>{
            return v.value/m.value
        })
        const style = computed(()=>{
            return {
                "--ph-progressbar-height":bh.value+"px"
            }
        })
        const cn = computed(()=>{
            const type = props.type||"primary"
            const cns = ["ph-progress","ph-progress-"+type]
            if(props.striped)
                cns.push("ph-progress-striped");
            if(props.striped&&props.animate)
                cns.push("ph-progress-animate")
            if(bh.value<=14)
                cns.push("ph-progress-small")
            else
                cns.push("ph-progress-large")
            
            return cns.join(" ")
        })
        const transform = computed(()=>{
            const v1 = (per.value-1)*100
            return {
                transform:`translateX(${v1}%)`
            }
        })
        const labelTransform = computed(()=>{
            let v = 0
            if(bh.value>14){
                v = per.value*ofw.value
                v = v<5?5:v-5
            }
            return {
                transform:`translateX(${v}px)`,
                color:v>5?'#FFF':'#666'
            }
        })
        onMounted(()=>{
            if(bh.value>14)
            ofw.value = indicator.value?.offsetWidth as number
        })
        const progress = computed(()=>{
            if(props.format==="%")
                return (per.value*100).toFixed(0)+"%"
            return props.format.replace(/(v|m)/g,(a:string,b:string)=>{
                return (b==="v"?v.value:m.value)+""
            })
        })
        return {cn,style,transform,labelTransform,progress,indicator}
    }
})
</script>
<style lang="scss" scoped>
@keyframes phtransalways{
    0% {background-position-x: 50%;}
    100% {background-position-x: 0%;}
}
.ph-progress{
    position: relative;
    flex-shrink: 0;
    height: calc(var(--phx) * 2.2857);
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 0 var(--ph-10);
    width: 100%;
    --ph-pb-indicator:var(--ph-c);
    &-label{
        display:block;
        flex:0 0 auto;
        height: var(--phx);
        line-height: var(--phx);
        z-index: 3;
        font-size: var(--ph-fs-small);
        position: relative;
        &:after{
            position: absolute;
            height: var(--phx);
            top:0;
            right:0;
            content: attr(ph-label);
            transform-origin: right;
            transform: scale(0.8);
            white-space: nowrap;
        }
    }
    .ph-indicator-wrap{
        flex:0 0 auto;
        position: relative;
        height:var(--ph-progressbar-height) ;
        overflow: hidden;
        border-radius: 10px;
        z-index: 2;
        background-color: #eee;
    }
    &-small{
        .ph-progress-label{
            right:0;
            top:0;
            left:auto;
            color:#666;
            align-self: flex-end;
        }
    }
    &-large{
        .ph-progress-label{
            position: absolute;
            color:#fff;
            left:var(--ph-10);
            top:1px;
            bottom:0;
            margin: auto;
        }
    }
    .ph-indicator{
        position: absolute;
        left:0;
        top:0;
        width:100%;
        height: 100%;
        transition: transform .3s linear;
        transform: translateX(-100%);
        border-radius: 10px;
        background-color: var(--ph-pb-indicator);
    }
    &-striped{
        .ph-indicator:after{
            content:"";
            position: absolute;
            border-radius: 10px;
            top:0;
            left:0px;
            bottom:0;
            right:1px;
            background-size: 20000% 100%;
            background-position-x: -10000%;
            background-image: repeating-linear-gradient(45deg,#FFFFFF33 0px,#FFFFFF33 10px,transparent 10px,transparent 20px);
        }
    }
    &-animate{
        .ph-indicator:after{
            animation: phtransalways 1000s linear infinite;
        }
    }
    &-primary{
        --ph-pb-indicator: var(--ph-primary);
    }
    &-info{
        --ph-pb-indicator: var(--ph-info);
    }
    &-success{
        --ph-pb-indicator: var(--ph-success);
    }
    &-warning{
        --ph-pb-indicator: var(--ph-warning);
    }
    &-danger{
        --ph-pb-indicator: var(--ph-danger);
    }
}
</style>